
{-# LANGUAGE TypeOperators, EmptyDataDecls #-}
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances, UndecidableInstances, IncoherentInstances #-}
{-# LANGUAGE DeriveDataTypeable #-}

module ORel.Types
    ((:::), Nil, PropType, PropAdd, Subtype)
    where

import Data.Typeable

infixr 5 ::: 
data hd ::: tl deriving Typeable
data Nil deriving Typeable


class FAIL_NoSuchProperty x
class    PropType prop objTy propTy | prop objTy -> propTy
instance PropType prop ((prop,propTy) ::: tl) propTy
instance PropType prop tl propTy => PropType prop (h ::: tl) propTy
instance FAIL_NoSuchProperty (prop,propTy) => PropType prop Nil propTy


class    PropAdd pt propSet propSet' | pt propSet -> propSet'
instance PropAdd pt Nil (pt ::: Nil)
instance PropAdd pt tl tl' => PropAdd pt (h ::: tl) (h ::: tl')
instance PropAdd (p,t) ((p,t') ::: tl) ((p,t') ::: tl)


-- obj1 является подтипом obj2
-- т.е. множество атрибутов obj2 является подмножеством множества атрибутов obj1
class    Subtype obj1 obj2
instance Subtype obj1 Nil
instance (PropType prop obj1 propTy, Subtype obj1 obj2) => Subtype obj1 ((prop,propTy) ::: obj2)

